iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
佛心分享-SideProject30

就決定是你了!打造寶可夢持有追蹤系統 (React x Express)系列 第 7

DAY 7:規劃關聯式資料表 (寶可夢基礎資料與持有紀錄)

  • 分享至 

  • xImage
  •  

今日目標說明

今天我們要進入資料庫設計的核心環節。我們的系統分為兩種資料:「全世界共用的寶可夢基礎資料 (圖鑑)」以及「每個玩家自己擁有的捕獲紀錄」。要怎麼在資料庫中優雅地儲存這些資料呢?

核心程式碼片段

我們使用了兩張主要的資料表,並透過 pokemon_idplayer_id 建立關聯:

-- 1. 寶可夢基礎圖鑑表 (全站共用)
CREATE TABLE pokemon_base (
    pokemon_id INTEGER PRIMARY KEY, -- 全國圖鑑編號
    name_zh TEXT NOT NULL,
    name_en TEXT NOT NULL,
    generation INTEGER,
    -- (其他基礎屬性省略)
);

-- 2. 玩家持有紀錄表 (每個人抓到的各不相同)
CREATE TABLE user_pokemon_holdings (
    holding_id INTEGER PRIMARY KEY AUTOINCREMENT,
    player_id TEXT NOT NULL,            -- 這是誰抓的?
    pokemon_id INTEGER NOT NULL,        -- 抓到哪隻? (Foreign Key)
    gender TEXT,                        -- 公、母或無性別
    is_shiny BOOLEAN DEFAULT 0,         -- 是否為色違
    is_lucky BOOLEAN DEFAULT 0,         -- 是否為亮晶晶
    notes TEXT,                         -- 玩家自訂備註
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (pokemon_id) REFERENCES pokemon_base(pokemon_id)
);

【架構決策對比】為什麼要用 Foreign Key (外鍵) 拆表?

新手在設計資料庫時,很容易把所有東西塞在同一張表裡(這稱為反正規化 Denormalization),例如在持有紀錄表裡面,除了存玩家 ID,還直接存下寶可夢的名字、屬性、世代。

為什麼我們堅持要把「圖鑑」和「持有紀錄」拆成兩張表,並用 Foreign Key (正規化 Normalization) 關聯呢?

  • 節省空間 (避免資料冗餘):如果有 100 個人都抓到了皮卡丘,我們不需要在資料庫裡寫 100 次「電屬性、關都地區」。只要存下 pokemon_id = 25,節省大量儲存空間。
  • 維護一致性:如果有一天官方宣布皮卡丘多了某個新屬性,我們只需要去 pokemon_base 改一次,所有玩家的皮卡丘屬性就會瞬間全部更新!
  • Foreign Key 的保護:我們加上了 FOREIGN KEY (pokemon_id) REFERENCES pokemon_base(pokemon_id),這確保了玩家絕對不可能抓到一隻「圖鑑上不存在 (id=9999)」的幽靈寶可夢,資料庫會在寫入時直接擋下這種錯誤資料。

實際畫面截圖

user_pokemon_holdings資料表

使用資料庫視覺化工具 (例如 Turso Studio) 顯示 user_pokemon_holdings 表格 Schema (欄位定義) 的畫面。

小結

資料表結構規劃完畢,正規化的設計讓我們未來的維護更加輕鬆!有了資料表,明天我們要開始來處理系統的安全大門:「封閉式使用者帳號系統」。


上一篇
DAY 6:後端第一支 API 實作 (RESTful 路由設計)
系列文
就決定是你了!打造寶可夢持有追蹤系統 (React x Express)7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言